home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The 640 MEG Shareware Studio 2
/
The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO
/
clang
/
nn.zip
/
ARTICLES.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-12-29
|
9KB
|
413 lines
/*
* access - get access to master data
*/
#include "config.h"
#include "db.h"
#include "articles.h"
#include "match.h"
/*
* memory management
*/
static thunk
dummy_str_t = {
NULL,
NULL,
0L
},
dummy_art_t = {
NULL,
NULL,
0L
};
static thunk *first_str_t = &dummy_str_t;
static thunk *current_str_t = &dummy_str_t;
static thunk *first_art_t = &dummy_art_t;
static thunk *current_art_t = &dummy_art_t;
static long cur_str_size = 0, cur_art_size = 0;
static char *next_str;
static article_header *next_art, **art_array;
static article_number max_articles = 0, mem_offset = 0;
/*
* allocate one article header
*/
#ifndef ART_THUNK_SIZE
#define ART_THUNK_SIZE 127
#endif
static new_thunk(t, ptr, size, chk_msg)
thunk *t;
char *ptr;
long size;
char *chk_msg;
{
thunk *new;
mem_check(ptr, (int)size, chk_msg);
new = (thunk *)calloc(1, sizeof(thunk));
mem_check((char *)new, sizeof(thunk), "memory thunk");
new->next_thunk = t->next_thunk;
t->next_thunk = new;
new->this_thunk = ptr;
new->thunk_size = size;
}
article_header *alloc_art()
{
if (cur_art_size == 0) {
if (current_art_t->next_thunk == NULL)
new_thunk(current_art_t,
calloc(ART_THUNK_SIZE, sizeof(article_header)),
(long)ART_THUNK_SIZE,
"article headers");
current_art_t = current_art_t->next_thunk;
next_art = (article_header *)current_art_t->this_thunk;
cur_art_size = current_art_t->thunk_size;
}
cur_art_size--;
return next_art++;
}
/*
* allocate a string of length 'len'
*/
#ifndef STR_THUNK_SIZE
#define STR_THUNK_SIZE ((1<<14) - 32) /* leave room for malloc header */
#endif
char *alloc_str(len)
int len;
{
char *ret;
if (cur_str_size <= len) { /* must be room for len+1 bytes */
if (current_str_t->next_thunk == NULL)
new_thunk(current_str_t,
malloc(STR_THUNK_SIZE),
(long)STR_THUNK_SIZE,
"string bytes");
current_str_t = current_str_t->next_thunk;
next_str = current_str_t->this_thunk;
cur_str_size = current_str_t->thunk_size;
}
ret = next_str;
cur_str_size -= len + 1;
next_str += len;
*next_str++ = NUL; /* string is null terminated */
return ret;
}
/*
* "free" the allocated memory
*/
free_memory()
{
current_str_t = first_str_t;
current_art_t = first_art_t;
cur_str_size = 0;
cur_art_size = 0;
n_articles = 0;
}
/*
* mark/release memory
*/
mark_str(str_marker)
string_marker *str_marker;
{
str_marker->sm_cur_t = current_str_t;
str_marker->sm_size = cur_str_size;
str_marker->sm_next = next_str;
}
release_str(str_marker)
string_marker *str_marker;
{
current_str_t = str_marker->sm_cur_t;
cur_str_size = str_marker->sm_size;
next_str = str_marker->sm_next;
}
mark_memory(mem_marker)
memory_marker *mem_marker;
{
mark_str(&(mem_marker->mm_string));
mem_marker->mm_cur_t = current_art_t;
mem_marker->mm_size = cur_art_size;
mem_marker->mm_next = next_art;
mem_marker->mm_nart = n_articles;
mem_offset += n_articles;
n_articles = 0;
articles = art_array + mem_offset;
}
release_memory(mem_marker)
memory_marker *mem_marker;
{
release_str(&(mem_marker->mm_string));
current_art_t = mem_marker->mm_cur_t;
cur_art_size = mem_marker->mm_size;
next_art = mem_marker->mm_next;
n_articles = mem_marker->mm_nart;
mem_offset -= n_articles;
articles = art_array + mem_offset;
}
/*
* merge all memory chunks into one.
*/
merge_memory()
{
n_articles += mem_offset;
mem_offset = 0;
articles = art_array;
}
/*
* save article header in 'articles' array
* 'articles' is enlarged if too small
*/
#define FIRST_ART_ARRAY_SIZE 500 /* malloc header */
#define NEXT_ART_ARRAY_SIZE 512
add_article(art)
article_header *art;
{
register long n;
if ((n_articles + mem_offset) == max_articles) {
/* must increase size of 'articles' */
if (max_articles == 0) {
/* allocate initial 'articles' array */
max_articles = FIRST_ART_ARRAY_SIZE;
n = 0;
} else {
new_thunk(current_str_t,
(char *)art_array,
(long)(max_articles*sizeof(article_header **)),
"");
n = max_articles;
articles = art_array + n;
max_articles += NEXT_ART_ARRAY_SIZE;
}
art_array = (article_header **)
calloc((unsigned)max_articles, sizeof(article_header **));
mem_check((char *)art_array, (int)max_articles, "article headers");
while (--n >= 0) art_array[n] = *--articles;
articles = art_array + mem_offset;
}
articles[n_articles] = art;
n_articles++;
}
static char match_subject[128] = {
/* NUL SOH STX ETX EOT ENQ ACK BEL BS TAB NL VT FF CR SO SI */
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
/* DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US */
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
/* SP ! " # $ % & ' ( ) * + , - . / */
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 99, 00, 00, 00, 00,
/* ^^ */
/* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 00, 00, 00, 00, 00, 00,
/* @ A B C D E F G H I J K L M N O */
00, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
/* P Q R S T U V W X Y Z [ \ ] ^ _ */
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 00, 00,
/* ` a b c d e f g h i j k l m n o */
00, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
/* p q r s t u v w x y z { | } ~ DEL */
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 00, 00
};
static article_comp(ah1, ah2)
article_header **ah1, **ah2;
{
register char *a = (**ah1).subject, *b = (**ah2).subject;
register p;
for (;; a++, b++) {
while (*a && MATCH_DROP(match_subject, *a)) a++;
while (*b && MATCH_DROP(match_subject, *b)) b++;
if (*a == NUL) {
if (*b) return -1;
break;
}
if (*b == NUL) return 1;
if (p = MATCH_CMP(match_subject, *a, *b)) return p;
}
/*
if (p = (**ah1).replies - (**ah2).replies) return p;
*/
if ((**ah1).t_stamp > (**ah2).t_stamp) return 1;
if ((**ah1).t_stamp == (**ah2).t_stamp) return 0;
return -1;
}
static article_equal(ah1, ah2) /* ah1.hdr == ah2.hdr */
article_header **ah1, **ah2;
{
register char *a = (**ah1).subject, *b = (**ah2).subject;
for (;; a++, b++) {
while (*a && MATCH_DROP(match_subject, *a)) a++;
while (*b && MATCH_DROP(match_subject, *b)) b++;
if (*a == NUL) {
if (*b == NUL) break;
goto not_equal;
}
if (*b == NUL) goto not_equal;
if (MATCH_EQ(match_subject, *a, *b)) continue;
goto not_equal;
}
return 1;
not_equal:
return 0;
}
sort_articles()
{
register article_header **app;
register long n;
if (n_articles <= 1) return;
qsort((char *)articles, (int)n_articles, sizeof(article_header *), article_comp);
for (n = n_articles - 1, app = articles + 1; --n >= 0; app++)
if (article_equal(app, app - 1)) (**app).flag |= A_SAME;
}
static offset_cmp(a, b)
article_header **a, **b;
{
register long i;
if ((i = (int)((*a)->a_number - (*b)->a_number)) == 0)
i = (*a)->fpos - (*b)->fpos;
return (i > 0) ? 1 : (i < 0) ? -1 : 0;
}
static age_cmp(ah1, ah2)
article_header **ah1, **ah2;
{
if ((**ah1).t_stamp > (**ah2).t_stamp) return 1;
if ((**ah1).t_stamp == (**ah2).t_stamp) return 0;
return -1;
}
unsort_articles(arrival)
{
register article_number i;
for (i = n_articles; --i >= 0;)
articles[i]->flag &= ~A_SAME;
if (n_articles <= 1) return;
qsort((char *)articles, (int)n_articles, sizeof(article_header *),
arrival ? offset_cmp : age_cmp);
}
/*
* Eliminate articles with the A_KILL flag set preserving the present ordering.
* This will only release the last entries in the articles array.
* Neither strings nor articles headers are released.
*/
elim_articles(list, list_lgt)
register article_number *list;
int list_lgt;
{
register article_header **srca, **desta;
register article_number n, count;
int changed, llen;
count = 0;
changed = 0, llen = 0;
for (n = 0, srca = desta = articles; n < n_articles; n++, srca++) {
if ((*srca)->flag & A_KILL) {
if (list_lgt > 0) {
if (n < *list) {
if (llen) changed = 1;
} else
if (n == *list) {
if (llen) {
llen++;
list_lgt--;
*list++ = -1;
} else
++(*list);
changed = 1;
}
}
continue;
}
if (list_lgt > 0 && n == *list) {
*list++ = count;
list_lgt--;
llen++;
}
count++;
*desta++ = *srca;
}
if (list_lgt > 0) {
if (!llen) *list = 0;
changed = 1;
}
n_articles = count;
return changed;
}